#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include <ecgi.h>
#include <memfile.h>

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xmlsave.h>

#include <xmlsec/buffer.h>
#include <xmlsec/xmldsig.h>
#include <xmlsec/xmltree.h>

#include "common.h"

static void die(int code, char *msg) {
  printf("Status: %d %s\n\n", code, msg);
  exit(0);
}

int main(int argc, char **argv) {
  const char *s, *param = "authority", *ip;
  int fd, ret, i;
  MFILE *m;
  xmlDocPtr doc;
  xmlNodePtr root;
  xmlSaveCtxtPtr ctxt;
  struct signedDocument *sdoc;
  xmlBufferPtr buf;

  close(2);
  ip = getenv("REMOTE_ADDR");
  if(!ip)
    die(500, "No REMOTE_ADDR set");
  fd = open("/tmp/cgi-stderr.log", O_WRONLY|O_CREAT|O_TRUNC, 0666);
  assert(fd >= 0);
  if(fd != 2) {
    close(2);
    if(dup2(fd, 2) != 2)
      die(500, "dup2 failed");
    close(fd);
  }
  assert(cgiInit() == ECGI_SUCCESS);
  cgiSetMaxSize(50000);		/* *handwave* */
  switch((ret = cgiGetKind(param))) {
  case 0:
    printf("Expecting a form variable\n");
    exit(0);
  case CgiKindValue:
    s = cgiParam(param);
    goto out;
  default:
    printf("ecgi supplying garbage (%d) in cgiGetKind()", ret);
    exit(0);
  case CgiKindFile:
    break;
  }

  m = cgiGetMFile(param);
  s = mfGetData(m);
out:
#if 1
  fd = open("/tmp/dump", O_CREAT|O_WRONLY|O_TRUNC, 0666);
  write(fd, s, strlen(s));
  close(fd);
#endif
  libSetup();
  doc = xmlParseMemory(s, strlen(s));
  if(!doc)
    die(400, "XML parsing failed");
  root = xmlDocGetRootElement(doc);
  if(!root)
    die(500, "No root element in document");
  assert(xmlSecCheckNodeName(root, "authority", ns_payment));
  sdoc = validateDocument("file://" DATADIR "/charon.xsd", root);
  assert(sdoc && sdoc->signedRoot);
  assert(xmlSecCheckNodeName(sdoc->signedRoot, "authority", ns_payment));
  buf = xmlBufferCreate();
  printf("Content-type: text/html\n\n");
  ctxt = xmlSaveToBuffer(buf, "UTF-8", XML_SAVE_NO_EMPTY|XML_SAVE_NO_DECL);
  xmlSaveDoc(ctxt, doc);
  xmlSaveClose(ctxt);
  printf("<HTML><HEAD><TITLE>Payment Authority Receipt</TITLE></HEAD><SCRIPT TYPE='text/javascript' LANG='javascript'>\n");
  printf("var authority = '");
  for(i = 0; i < buf->use; i++) {
  	switch(buf->content[i]) {
		case '\n':
			fputs("\\n", stdout);
			break;
		case '\r':
			fputs("\\r", stdout);
			break;
		case '\'':
		case '\\':
			putchar('\\');
		default:
			putchar(buf->content[i]);
			break;
	}
  }
  printf("';\n");
  printf("if(window.opener.processAuthority(authority)) window.close();\n");
  printf("</SCRIPT></HEAD><BODY><P>Please wait...</P></BODY></HTML>\n");
  return 0;
}
